import src from './source';
import loadjs from 'loadjs';
import * as _ from './common';
import { registerFormula } from './FormulaNew';
import WfForm_Public from './interface';
import {toJS} from "mobx";
import * as FieldUtil from "./fieldUtil";


export const commonParamRange = [
    "verifyRight", "requestid", "workflowid", "nodeid", "formid", "isbill", "f_weaver_belongto_userid", "f_weaver_belongto_usertype","zqyjfieldid",
    "authStr", "authSignatureStr", "signatureSecretKey", "signatureAttributesStr", "titlename", "workflowname","currentnodetype" ,"nodetype", "nodename",
    "iscreate", "isviewonly", "isaffirmance", "isshared", "iswfshare", "ismode", "modeid", "isagent", "beagenter", "creater", "creatertype",
    "requestType", "isprint", "wfmonitor", "isrequest", "desrequestid", "custompage", "docViewUrl", "fileViewUrl", "layouttype","layoutversion","isFree",
    "isHideArea","isHideInput", "intervenorright", "isWorkflowDoc", "flowDocFieldId", "needconfirm", "currentnodeid", "isurger", "newdocpath",
    "belongTest","wfTestStr","billIncludePage", "margin", "printLogListFlag", "helpdocid","isremark","takisremark","isOpenCommunication","hasNewCommunication",
    "showDefaultSign","showDefaultLogList","agentType","agentorByAgentId","selectNextFlow","hasFreeNode","freeNodeExtendNodeId","isNeedFlowFreeNodeTips","canSubmitToRejectNode",
    "billIncludePage4mobile","address","position","showLayoutSwitch", "layoutAnalysisType","mobileSupportViewFileType","waterMarkInfo",     //移动端独有
    "apiResultCacheKey","selectNextFlowPattern","showFreeWfSimpleCom", "existSynergy", "languageid", "lastname","msgSubmitFormAction","appDetachDisableAll","allowAllPersonGroup",
    "openAutoForecast", "showAutoForecastResult","iscowork","coworkid","needReloadList","currentNodeAttribute","useInvoiceCloud","signFilter","isfreecomfirm","intervenorright_dev"
];

export const commonApiParamRange = [
    "requestid", "workflowid", "nodeid", "formid", "isbill", "f_weaver_belongto_userid", "f_weaver_belongto_usertype",
    "authStr", "authSignatureStr", "signatureSecretKey", "signatureAttributesStr", "nodetype", "iscreate", "isfromtab",
    "isviewonly", "isaffirmance", "isshared", "iswfshare", "ismode", "modeid","isagent", "beagenter", "toexcel", "creater", "needconfirm",
    "creatertype", "requestType", "isprint", "wfmonitor", "isurger", "intervenorright","isSubmitDirect","selectNextFlow",
    "agentType","agentorByAgentId", "layouttype", "freeNodeExtendNodeId", "apiResultCacheKey","intervenorright_dev"
];

export const baseParamRange = ["requestid", "workflowid", "nodeid", "formid", "isbill", "f_weaver_belongto_userid", "f_weaver_belongto_usertype", "languageid"];

export const importantParamRange = ["requestid", "workflowid", "nodeid", "formid", "isbill", "f_weaver_belongto_userid", "f_weaver_belongto_usertype",
    "src", "remark", "authStr", "iscreate", "authSignatureStr", "signatureSecretKey", "signatureAttributesStr"
];

//获取自定义页面列宽
export const generateCustomPageList = () =>{
    //先加载自定义页面，顺序：全局自定义页面、单据自定义页面、路径自定义页面
    const { commonParam } = src.globalStore;
    const { billIncludePage="",custompage } = commonParam;
    let customArr = custompage.jspPage || [];
    customArr.push(billIncludePage);
    const tmp = new Map();
    customArr = customArr.filter(item => item !== "" && !tmp.has(item) && tmp.set(item, true));     //去重替空值
    return customArr;
}

//获取模板代码开发Promise列表
export const generateScriptPromiseList = () =>{
    loadInjectDevFiles();   //注入自定义开发文件列表
    const { API_REQ,globalStore,layoutStore } = src;
    const { isSourceLayout,urlParams,commonParam,commonApiParam } = globalStore;
    const customParam = {...urlParams, ...commonApiParam};
    const customArr = generateCustomPageList();
    /* eslint no-console: 0 */
    if(window.console)  console.log("customPageArr:", customArr);

    let promiseList = [];
    customArr && customArr.forEach(item =>{
        promiseList.push(API_REQ.loadCustompage(item, customParam));
    });
    //再加载代码块
    if(!isSourceLayout){
        promiseList.push(API_REQ.loadScriptContent({layoutid: commonParam.modeid}));
    }else{
        promiseList.push(new Promise((resolve)=>{
            resolve("");
        }));
    }
    return promiseList;
}

//加载自定义的JS/CSS文件
export const loadCustomFiles = (flag) =>{
    const { commonParam } = src.globalStore;
    const custompage = commonParam.custompage;
    const files = flag === "css" ? custompage.cssPage : (flag === "js" ? custompage.jsPage : []);
    loadjs(files||[], {
        success: () =>{
            /* eslint no-console: 0 */
            if(window.console)  console.log("加载自定义开发文件:", files);
        }
    });
}

//加载新版公式JS资源并触发公式注册
export const loadFormulaResource = () =>{
    const { linkageCfg } = src.layoutStore;
    const { files=[] } = linkageCfg.formulaCfg || {};
    const fn = () =>{
        //加载完执行事件
        registerFormula();
    }
    loadjs.isDefined('formula') ? loadjs.ready('formula', fn) : loadjs(files, 'formula', fn);
}

//加载二开注入的JS资源
export const loadInjectDevFiles = () =>{
    const { commonApiParam } = src.globalStore;
    src.API_REQ.loadInjectDevFile({...commonApiParam}).then(data =>{
        const files = data.files;
        if(files && files.length > 0){
            const init = () => {
                if(window.console)  console.log("加载二开注入JS文件成功", files);
            };
            loadjs.isDefined('customDev') ? loadjs.ready('customDev', init) : loadjs(files, 'customDev', init);
        }
    });
}

//代码块中<script id>标签转换处理
export const manageScriptContent = (content) =>{
    if(!content)
        return "";
    const { propFileCfg } = src.layoutStore;
    const script_debug = propFileCfg && propFileCfg.script_debug == "1";
    //script标签存在自定义属性的，生成个空span兼容
    const reg = new RegExp("<script .*?id=.*?></script>|<script .*?id=.*?/>", "ig");
    const arr = content.match(reg);
    let appendScriptSpan = "";
    arr && arr.map(v =>{
        appendScriptSpan += v.replace(new RegExp("(<|/)script","ig"), "$1span");
    });
    //document.write覆写Dom结构兼容
    content = content.replace(/document.write/g, 'jQuery("#scriptArea").append');
    //剔除html头等信息
    content = content.replace(/<(\/?)(html|body|head)>/ig, "");
    //剔除部分JS文件引入导致异常
    const filterSrcArr = [
        "/wui/common/jquery/plugin/Listener_wev8.js",
        "/js/workflow/VCEventHandle_wev8.js"
    ];
    if(script_debug){
        //引入的JS文件单独拎出loadjs发请求，才能调试及报错提示
        // <!-- script -->  这种注释代码不好正则抓取，先直接剔除
        content = content.replace(new RegExp("<!--[\\s\\S]*?script[\\s\\S]*?-->", "ig"), "");
        // const matchJSFile = new RegExp("(?<!<!--\s*?)(<script.*? src=.*?(></script>|/>))(\s*?)(?!-->)", "ig");
        const matchJSFile = new RegExp("<script.*? src=.*?(></script>|/>)", "ig");
        const matchJSSrc = new RegExp(" src *?= *?[\"|'](.*?)[\"|']", "i");
        const JSFileArr = content.match(matchJSFile);
        const JSFileSrcArr = [];
        JSFileArr && JSFileArr.forEach(item =>{
            const JSSrcArr = item.match(matchJSSrc);
            if(JSSrcArr && JSSrcArr.length >= 2){
                const JSSrc = JSSrcArr[1];
                content = content.replace(item, "");   //满足loadjs条件，原JS引入剔除
                if(!_.includes(filterSrcArr, JSSrc))
                    JSFileSrcArr.push(JSSrc);
            }
        });
        const loadScriptFn = () =>{
            //需要JS文件加载完再加载script块，script块加载到head层，能抛出错误，在代码块内加上debugger标记才可定位调试
            const matchScript = new RegExp("<script.*?>([\\s\\S]*?)</script>", "ig");
            const scriptArr = content.match(matchScript);
            scriptArr && scriptArr.forEach(item =>{
                content = content.replace(item, "");
                const source = item.replace(matchScript, "$1");
                const oHead = document.getElementsByTagName("HEAD").item(0);
                const oScript = document.createElement("script");
                oScript.language = "javascript";
                oScript.type = "text/javascript";
                oScript.id = "custom_script_"+new Date().getTime();
                oScript.defer = true;
                oScript.text = source;
                oHead.appendChild(oScript);
            });
        }
        if(JSFileSrcArr.length > 0){
            loadjs(JSFileSrcArr, {
                success: () =>{
                    loadScriptFn();
                },
                error: () =>{
                    /* eslint no-console: 0 */
                    if(window.console.error)  console.error("加载自定义开发引入的JS文件失败:", JSFileSrcArr);
                    loadScriptFn();
                }
            });
        }else{
            loadScriptFn();
        }
    }else{
        filterSrcArr.forEach(item =>{
            content = content.replace(new RegExp("<script .*?"+item+".*?></script>|<script .*?"+item+".*?/>","ig"), "");
        });
    }
    return content + appendScriptSpan;
}

//将富文本中link引入的CSS文件单独提取出链接，改为text请求方式再包层作用域，解决CSS污染问题
//暂定只处理富文本字段污染，不处理代码块以及自定义页面，防止用户本身就是想更改表单布局外层
export const manageCssFilePollute = (content, swapClassName) =>{
    if(!content || !swapClassName)
        return content;
    const reg = new RegExp("<link .*?href=(.*?\\.css).*?></link>|<link .*?href=(.*?\\.css).*?/>", "ig");
    let cssFiles = [];
    const arr = content.match(reg);
    if(arr && arr.length > 0){
        content = content.replace(reg, "");     //原样式请求替换为空
        arr.map(item =>{
            reg.test(item);
            let href = RegExp.$1 || RegExp.$2 || "";
            if(href !== ""){
                href = href.replace(new RegExp("\"|'","ig"), "");
                cssFiles.push(href);
            }
        });
    }
    loadCssFileContent(cssFiles, swapClassName);
    return content;
}

//加载css文件并限制作用域
export const loadCssFileContent = (cssFiles=[], swapClassName) =>{
    cssFiles && cssFiles.map(href =>{
        src.API_REQ.loadHrefTextContent(href, {v:new Date().getTime()}).then(cssText =>{
            cssText = cssText.replace(new RegExp("/\\*[\\s\\S]*?\\*/","ig"), "");   //注释剔除
            cssText = cssText.replace(new RegExp("\}([\\s\\S]*?)\{","ig"), "}\n."+swapClassName+" $1{");
            cssText = `<style>.${swapClassName} ${cssText}</style>`;
            window.jQuery("body").append(cssText);
        });
    });
}

//判断模板是否包含开启横向滚动条的明细
export const judgeExistXScrollDetail = () => {
    let exist = false;
    const { tableInfo } = src.layoutStore;
    _.forIn(tableInfo, (v,k) =>{
        if(k.indexOf("detail") > -1){
            const { allowscroll,mobileallowscroll } = v.detailtableattr;
            if((!src.isMobile && allowscroll === 1) || (src.isMobile && mobileallowscroll === 1)){
                exist = true;
                return false;
            }
        }
    });
    return exist;
}

//自定义注册事件校验
export const verifyCustomRegisterEvent = (params, callback, registerFnParams={}) => {
    let result = null;
    const opertype = convertOpertype(params);
    const eventArr = opertype === null ? new Array() : WfForm_Public.eventList[opertype];
    //存在注册事件
    if (typeof eventArr === "object" && eventArr.length > 0) {
        let index = 0;
        const executeVerify = () => {
            if (index < eventArr.length) {
                eventArr[index++](() => {
                    executeVerify();
                }, registerFnParams);
            } else {
                result = callback();
            }
        }
        executeVerify();
    } else {
        result = callback();
    }
    return result;
}

const convertOpertype = (params) => {
    if (typeof params === "string")
        return params;
    const actiontype = params.actiontype;
    const src = params.src;
    if (params.isaffirmance == "1")     //确认动作
        return actiontype === "requestOperation" && src === "save" ? WfForm_Public.OPER_SUBMITCONFIRM : null;
    if (actiontype === "remarkOperation" && src === "save")
        return WfForm_Public.OPER_REMARK;
    else if (actiontype === "requestOperation") {
        if (src === "reject" || (src === "save" && params.isaffirmanceSrc === "reject"))
            return WfForm_Public.OPER_REJECT;
        else if (src === "submit")
            return WfForm_Public.OPER_SUBMIT;
        else if (src === "intervenor")
            return WfForm_Public.OPER_INTERVENE;
        else if (src === "save")
            return WfForm_Public.OPER_SAVE;
    }
    return null;
}

/**
 * 执行表单右键事件
 * @param item btn对象
 * @param rightBtn
 */
export const executeRightBtnClick = (item = {},rightBtn = {}) => {
    const clickFn = () => {
        const {type, menuFun,funParams = {}} = toJS(item);
        let fn = menuFun.indexOf('this') >= 0 ? `${menuFun.split('this')[0]})` : menuFun;
        const fnName = fn.substring(0,fn.indexOf("("));

        if(type && type.indexOf("BTN_CUSTOMIZE") > -1){
            //window[fnName](fnParamArr);
            eval(fn);
        } else {
            execOperateFun(fnName,funParams,rightBtn);
        }
    }
    verifyCustomRegisterEvent(WfForm_Public.OPER_BEFORECLICKBTN,clickFn,toJS(item));
}
//执行右键函数
const execOperateFun = (fun = '',funParams = {},rightBtn = {}) => {
    if(typeof rightBtn[fun] == "function") {
        if(fun === 'doSubmit_Pre') {
            const {src = 'submit'} = funParams;
            rightBtn[fun](src);
        } else if (fun === 'doSubmitDirect') {
            const {subfun} = funParams;
            rightBtn[fun](subfun);
        } else if (fun === 'aboutVersion'){
            const {versionid} = funParams;
            rightBtn[fun](versionid);
        } else if (fun === 'triSubwf2') {
            let {subwfid, workflowNames,requestType} = funParams;
            rightBtn[fun](subwfid, workflowNames,requestType);
        } else if (fun === 'onCustomOpt') {
            const {reqid,wfid, menuid,nodeid} = funParams;
            rightBtn[fun](reqid,wfid, menuid,nodeid);
        } else if (fun === 'onNewRequest') {
            const {workflowid,requestid,agent} = funParams;
            rightBtn[fun](workflowid,requestid,agent);
        } else if (fun === 'onNewRequest2') {
            let {workflowid,requestid,nodeId,menuId,requestType} = funParams;
            rightBtn[fun](workflowid,requestid,nodeId,menuId,requestType);
        } else if (fun === 'onNewSms') {
            const {wfid, nodeid, reqid, menuid,isurger} = funParams;
            rightBtn[fun](wfid, nodeid, reqid, menuid,isurger);
        } else if(fun === 'onNewEmail') {
            const {reqid} = funParams;
            rightBtn[fun](reqid);
        } else if (fun === 'onNewChats') {
            const {wfid, nodeid, reqid, menuid} = funParams;
            rightBtn[fun](wfid, nodeid, reqid, menuid);
        } else {
            if(Object.keys(funParams).length > 0) {
                rightBtn[fun](funParams);
            } else {
                rightBtn[fun]();
            }
        }
    }
}


//流转表单图片显示设置
export const imageStyleHander = (propFileCfg) =>{
    const form_image_handWritingShowType = propFileCfg.form_image_handWritingShowType;
    const form_image_handWritingMaxHeight = propFileCfg.form_image_handWritingMaxHeight;
    let form_image_scalingRatio = propFileCfg.form_image_scalingRatio || 90;
    let imgStyle = "<style type=\"text/css\">\n .etype_5 img, .etype_3 .wf-form-textarea .wf-form-textarea-html-show img, .etype_3 .wf-richtext-view-text img {\n";
    imgStyle += "max-width:"+form_image_scalingRatio+"% !important\n}\n";
    if(form_image_handWritingShowType == "1" && form_image_handWritingMaxHeight != null && form_image_handWritingMaxHeight != ""){
        imgStyle += " .etype_5 img.handWrittenSign {\n max-height:"+form_image_handWritingMaxHeight+"px !important\n}\n";
    }
    imgStyle += "</style>";
    window.jQuery("body").append(imgStyle);
}


//手写签批，样式宽度单独计算
export const handWritingHander = (imgObj) =>{
	const { propFileCfg } = src.layoutStore;
	const form_image_handWritingShowType = propFileCfg.form_image_handWritingShowType;
	const form_image_handWritingMaxHeight = propFileCfg.form_image_handWritingMaxHeight;
    const form_image_handWritingMaxWidth = propFileCfg.form_image_handWritingMaxWidth;
    if(form_image_handWritingShowType == "1" && form_image_handWritingMaxHeight != null){
        return;
	}
	//既设置了最大宽度px，又设置了最大宽度百分比，则计算谁更小
	if(form_image_handWritingShowType == "2" && form_image_handWritingMaxWidth != null){
        let imgStyle = window.jQuery(imgObj).attr("style") || "";
        if(";" != imgStyle.charAt(imgStyle.length-1)){
            imgStyle += ";";
        }
        let imgWidth_td = window.jQuery(imgObj).closest("td.etype_5").width();
        const form_image_scalingRatio = propFileCfg.form_image_scalingRatio;
        const imgWidth_temp=imgWidth_td*form_image_scalingRatio/100;
        if(imgWidth_temp*10 > form_image_handWritingMaxWidth*10){
            imgStyle += "max-width: "+form_image_handWritingMaxWidth+"px !important";
        }else{
            imgStyle += "max-width: "+form_image_scalingRatio+"% !important";
        }
        window.jQuery(imgObj).css("cssText",imgStyle);
	}
}


//加载计算方法的资源
export const loadCaculateResource = ()=>{
    new Promise(resolve=>{
        const loadjs = window.loadjs;
        loadjs([`/js/workflow/caculate_wev8.js`], ()=>{
            resolve(true);
        })
    }).then(res => {
        src.globalStore.controlVariableMap("caculate_Complete", res);
    });
}

export const getWaterMarkFieldShowName = (fieldMark) => {
    if(fieldMark == 'field-2') {
        const vObj = WfForm_Public.getFieldValueObj(fieldMark);
        if(vObj) {
            const {specialobj = [],value} = vObj
            let result  = toJS(specialobj).filter((item) => item.id == value);
            if(result && result.length > 0) {
                return result[0].customname;
            }
        }
    }
    const fieldAttr = FieldUtil.getFieldAttr(fieldMark) || {};
    const {htmltype = 1,tableMark,selectattr = {},detailtype = ''} = fieldAttr;
    const fieldObj = WfForm_Public.getFieldValueObj(fieldMark) || {};
    const {value = '',specialobj} = fieldObj;
    switch (htmltype) {
        case 3:
            if(specialobj) {
                let browValNames = [];
                specialobj.map((item) => {
                    browValNames.push(item.name || '');
                })
                return browValNames.join(',');
            } else {
                return value;
            }
        case 5:
            const itemList = selectattr.selectitemlist;
            if(itemList) {
                let valArr = value.split(',');
                let result = [];
                toJS(itemList).map((item) => {
                    const {selectvalue = '',selectname = ''} = item;
                    if(valArr.indexOf(selectvalue.toString()) > -1) {
                        result.push(selectname);
                    }
                });
                return result.join(' ');
            }
            return value;
        case 6:
            if(specialobj) {
                const {filedatas = []} = specialobj;
                let fileNames = [];
                toJS(filedatas).map((item) =>{
                    fileNames.push(item.filename || '');
                })
                return fileNames.join(',');
            }
            return value;
        default:
            return WfForm_Public.getFieldValue(fieldMark);
    }
}

export const getUpdateReqInfoFieldValue = () => {
    const fieldVals = {};
    const {mainData, fieldAttrMap} = src.layoutStore;
    mainData.forEach((fieldObj, k) => {
        const fieldid = k.substring(5);
        if (fieldAttrMap.has(fieldid)) {
            const fieldAttr = fieldAttrMap.get(fieldid);
            const {fieldname = ''} = fieldAttr;
            if (fieldname == 'manager')
                fieldVals[k] = fieldObj.value;
        }
    });
    return fieldVals;
}